/*
 *  This sketch sends a message to a TCP server
 *
 */

#include <WiFi.h>
#include <WiFiMulti.h>
#include <ESP32Time.h>
#include <ArduinoJson.h>

// 宏定义 GPIO 输出引脚
#define LED_PIN   13
#define LED_PIN2   12
WiFiMulti WiFiMulti;
float distance1 = 0.0; // 距离1数据

const int TrigPin1 = 2;
const int EchoPin1 = 3;



unsigned long Time_Echo_us1 = 0;
unsigned long Len_mm1 = 0;
unsigned long LastD1 = 0;
unsigned long sec = 0;

WiFiClient client;
StaticJsonDocument<200> json;

ESP32Time rtc(28800);  // offset GMT8

void setup()
{
  sec++;
  Serial.begin(115200);
  delay(10);
  Serial.println(sec);

  pinMode(EchoPin1, INPUT); // Set EchoPin as input, to receive measure result from US-025,US-026
  pinMode(TrigPin1, OUTPUT);
    // 配置 GPIO 输出引脚
  pinMode(LED_PIN, OUTPUT);
  
  huxi_deng();

  // We start by connecting to a WiFi network
  WiFiMulti.addAP("xiaohe_mobile", "23456789");
  WiFiMulti.addAP("xiaohe", "23456789");
  WiFiMulti.addAP("wangke", "wxwk1898");

  Serial.println();
  Serial.println();
  Serial.print("Waiting for WiFi... ");


  while (WiFiMulti.run() != WL_CONNECTED)
  {
    Serial.print(".");
   
    delay(2);
    
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  analogWrite(LED_PIN, 10);
  pinMode(LED_PIN2, OUTPUT);
  delay(500);
}



void loop()
{

  cWifi();

  distance1 = readDistance1();
  distance1 = panduanJUli(distance1);

  // This will send a request to the server
  // uncomment this line to send an arbitrary string to the server
  // client.print("Send this data to the server");
  // uncomment this line to send a basic document request to the server

  Serial.print("{\"action\":\"door.v1.add\",\"sex\":1,\"distance\":" + String(distance1) + "}");
  client.println("{\"action\":\"door.v1.add\",\"sex\":1,\"distance\":" + String(distance1) + "}");

  int maxloops = 0;

  while (!client.available() && maxloops < 1000)
  {
    maxloops++;
    delay(1); // delay 1 msec
  }
  if (client.available() > 0)
  {
  
    String line = client.readStringUntil('\r');
    Serial.println(line);
    deserializeJson(json, line);
    if(json["success"] == true){
      rtc.setTime(json["time"]);
      Serial.print(rtc.getHour(true)); 
      Serial.print(":"); 
      Serial.print(rtc.getMinute());
      Serial.print(":"); 
      Serial.println(rtc.getSecond());  
    }
  }
  else
  {
    Serial.println("client.available() timed out ");
  }

  Serial.println("Closing connection.");
  // client.stop();

  // Serial.println("Waiting 1 seconds before restarting...");
  delay(1000);
}

void huxi_deng(){
    // 实现渐亮效果
  for(int i=0;i<200;i++) {
    // 设置亮度模拟值
    analogWrite(LED_PIN, i);
    // 延时 2ms
    delay(5);
    }
  // 实现渐灭效果
  for(int i=200;i>=0;i--) {
    // 设置亮度模拟值
    analogWrite(LED_PIN, i);
    // 延时 2ms
    delay(5);
  }
}

void cWifi()
{

  const uint16_t port = 8082;
  const char *host = "150.158.123.141"; // ip or dns

  // Use WiFiClient class to create TCP connections
  if (!client.connect(host, port))
  {
    Serial.println("Connection failed.");
    Serial.println("Waiting 5 seconds before retrying...");
    delay(5000);

    //判断 wifi 是否断网，如果断网就重连接 WiFi
    if (WiFiMulti.run() != WL_CONNECTED)
    {
      Serial.println("WiFi disconnected.");
      huxi_deng();

    }
     // 设置亮度模拟值
    analogWrite(LED_PIN, 10);
    return;
  }
  else
  {
    // Serial.print("Connecting to ");
    // Serial.println(host);
  }
}

long panduanJUli(long now)
{
  analogWrite(LED_PIN2, now);
  long piancha = 2;
  if (now != LastD1)
  {
    // if(now+piancha > LastD1 || now-piancha< LastD1){
    //   LastD1 = now;
    //   return now;
    // }
    LastD1 = now;
    return now;
  }
  else
  {
    if(now>560)
    {
      return 0;
    }else{
      return now;
    }

  }
}

long readDistance1()
{

  digitalWrite(TrigPin1, HIGH); // begin to send a high pulse, then US-025/US-026 begin to measure the distance
  delayMicroseconds(20);        // set this high pulse width as 20us (>10us)
  digitalWrite(TrigPin1, LOW);  // end this high pulse

  Time_Echo_us1 = pulseIn(EchoPin1, HIGH);            // calculate the pulse width at EchoPin,
  if ((Time_Echo_us1 < 60000) && (Time_Echo_us1 > 1)) // a valid pulse width should be between (1, 60000).
  {
    Len_mm1 = (Time_Echo_us1 * 34 / 1000) / 2; // calculate the distance by pulse width, Len_mm = (Time_Echo_us * 0.34mm/us) / 2 (mm)
    // Serial.print("Present Distance is: ");  //output result to Serial monitor
    Serial.print(Len_mm1, DEC); // output result to Serial monitor
    Serial.println("cm");
    if (Len_mm1 >= 560)
    {
      return 0;
    } // output result to Serial monitor
    return Len_mm1;
  }
  else
  {
    return 0;
  }
}
